<?php

namespace addons\yunfood\controller;


use addons\yunfood\library\Logic;
use addons\yunfood\library\Super;
use addons\yunfood\model\FundOrder;
use addons\yunfood\model\FundRecord;
use addons\yunfood\model\FundUser;
use addons\yunfood\model\FundPack;
use addons\yunfood\model\Payment;
use think\Db;
use think\Exception;
use think\exception\PDOException;

/**
 * 储值接口
 */
class Fund extends BaseApi
{
    /**
     * 获取会员页信息
     */
    public function getWrapData()
    {
        $cardInfo = ['number' => 0, 'amount_left' => 0];

        if ($fundUser = FundUser::get(['user_id' => $this->userId])) {
            $cardInfo['number'] = $fundUser->number;
            $cardInfo['amount_left'] = $fundUser->amount_left;
        }

        $packList = FundPack::where(['status' => FundPack::STATUS_NORMAL])->select();

        // 移除已超买套餐
        if ($packList) {
            $packIds = [];
            foreach ($packList as $item) {
                if ($item->user_limit) {
                    $packIds[] = $item->id;
                }
            }
            if ($packIds) {
                $dataList = FundOrder::field('fund_pack_id pack_id, count(*) count')
                    ->where(['user_id' => $this->userId, 'status' => FundOrder::STATUS_DONW])
                    ->where('fund_pack_id', 'in', $packIds)
                    ->group('fund_pack_id')->select()->toArray();
                if ($dataList) {
                    $orderCounts = array_column($dataList, 'count', 'pack_id');
                    foreach ($packList as $key => $item) {
                        if (! $item->user_limit) {
                            continue;
                        }
                        if ($limit = $orderCounts[$item->id] ?? 0) {
                            if ($limit >= $item->user_limit) {
                                unset($packList[$key]);
                            }
                        }
                    }
                }
            }
        }

        // 返回结果
        $packList = Super::arrayGetSet($packList, [
            'id',
            'name',
            'price'  => function ($item) {
                return (float)$item->price;
            },
            'amount' => function ($item) {
                return (float)$item->amount;
            },
        ], true);
        $packList = array_values($packList);

        $result = ['card_info' => $cardInfo, 'pack_list' => $packList];

        $this->success(__('success'), $result);
    }

    /**
     * 充值
     */
    public function recharge()
    {
        $fundPackId = $this->request->post('fund_pack_id');
        $channel = $this->request->post('channel');
        if (! $fundPack = FundPack::get(['id' => $fundPackId, 'status' => FundPack::STATUS_NORMAL])) {
            $this->error('储值套餐不存在');
        }
        if ($fundPack->amount <= 0) {
            $this->error('储值套餐金额无效');
        }
        $result = null;

        // 开启事务
        Db::startTrans();
        try {
            if ($fundPack->user_limit) {
                $fundOrderCount = FundOrder::where([
                    'user_id'      => $this->userId,
                    'fund_pack_id' => $fundPack->id,
                    'status'       => FundOrder::STATUS_DONW
                ])->count();
                if ($fundOrderCount >= $fundPack->user_limit) {
                    throw new Exception('已达到充值次数上限');
                }
            }
            if ($fundUser = FundUser::get(['user_id' => $this->userId])) {
                if ($fundUser->status != FundUser::STATUS_NORMAL) {
                    throw new Exception('账户被禁用，暂不能充值');
                }
            } else {
                $fundUser = new FundUser();
                $fundUser->number = Logic::generateBusinessNo('fund_user_no');
                $fundUser->user_id = $this->userId;
                $fundUser->status = FundUser::STATUS_NORMAL;
                $fundUser->save();
            }
            $fundOrder = FundOrder::where(['user_id' => $this->userId, 'fund_pack_id' => $fundPackId])
                ->order(['id' => SORT_DESC])->find();
            if ($fundOrder) {
                if ($fundOrder->status != FundOrder::STATUS_WAIT) {
                    $fundOrder = null;
                }
            }
            if ($fundOrder === null) {
                $fundOrder = new FundOrder();
                $fundOrder->order_no = date('YmdHis');
                $fundOrder->user_id = $this->userId;
                $fundOrder->fund_user_id = $fundUser->id;
                $fundOrder->fund_pack_id = $fundPackId;
                $fundOrder->payment_no = null;
                $fundOrder->status = FundOrder::STATUS_WAIT;
            }
            $fundOrder->fund_pack_name = $fundPack->name_text;
            $fundOrder->fund_pack_price = $fundPack->price;
            $fundOrder->fund_pack_amount = $fundPack->amount;
            $fundOrder->discount = bcsub($fundPack->amount, $fundPack->price, 2);
            $fundOrder->payment = $fundPack->price;

            // 支付数据
            $payment = Payment::getPaymentData(Payment::ORDER_TYPE_FUND, $fundOrder, $channel);
            if (! $payment) {
                throw new Exception('获取支付数据失败');
            }

            // 保存订单
            $fundOrder->payment_no = $payment->payment_no;
            $fundOrder->payment_status = FundOrder::PAYMENT_STATUS_WAIT;
            $fundOrder->save();

            // 支付信息
            $result = $payment->getPaymentResult();

            Db::commit();
        } catch (PDOException | \Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }

        $this->success('success', $result);
    }

    // 获取充值订单
    public function getOrderList()
    {
        // 数据列表
        $query = FundOrder::where(['user_id' => $this->userId, 'status' => FundOrder::STATUS_DONW])
            ->order(['id' => 'DESC']);

        $result = $query->paginate($this->request->post('page_size', 10), false);
        $result = Logic::getPageData($result, [
            'id',
            'fund_pack_name',
            'fund_pack_price',
            'fund_pack_amount',
            'discount',
            'payment',
            'payment_rel',
            'payment_time'
        ]);

        $this->success('success', $result);
    }

    // 获取交易记录
    public function getTradeList()
    {
        // 数据列表
        $query = FundRecord::where(['user_id' => $this->userId])
            ->order(['id' => 'DESC']);

        $result = $query->paginate($this->request->post('page_size', 10), false);
        $result = Logic::getPageData($result, [
            'id',
            'action',
            'action_text',
            'amount',
            'after_amount',
            'created_at',
        ]);

        $this->success('success', $result);
    }
}
